package model

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"math/rand"
	"os"
	sort2 "sort"
	"strconv"
	"strings"
	"time"
)

const (
	FILEPATH = "C:\\Users\\马军\\Desktop\\goland-workspace\\src\\goland-study\\src\\go_code\\basis\\testCode\\model\\file\\"
	FILENUM  = 10
)

func GoroutineTest2() {
	writerExit := make(chan int, FILENUM)
	SortExit := make(chan int, FILENUM)

	//开启10个协程完成文件的写操作
	for i := 0; i < FILENUM; i++ {
		go writerDataFile(writerExit, FILEPATH+"data"+strconv.Itoa(i)+".txt", i)
	}

	//开启10个协程来读取文件进行排序
	for i := 0; i < FILENUM; i++ {
		go sort(writerExit, SortExit, FILEPATH+"data"+strconv.Itoa(<-writerExit)+".txt")
	}

	for true {
		if len(SortExit) == FILENUM {
			fmt.Println("读取和写入文件完成。。")
			close(writerExit)
			break
		}
	}
}

//写入数据
func writerDataFile(writerExit chan int, filePath string, fileNum int) {
	fmt.Println("开始写入文件，路径=", filePath)
	rand.Seed(time.Now().UnixNano())
	//标记这是第几个文件
	writeFile(filePath, strconv.Itoa(fileNum)+";")
	str := ""
	for i := 0; i < 1000; i++ {
		num := rand.Intn(1000) + 1
		if i == 999 {
			str += strconv.Itoa(num)
		} else {
			str += strconv.Itoa(num) + ","
		}
	}
	writeFile(filePath, str)
	writerExit <- 1
}

//读取文件中的数据
func sort(writerExit chan int, SortExit chan int, filePath string) {
	for true {
		if len(writerExit) == FILENUM {
			//写完成
			fmt.Println("写完成，开始读取文件。。。")
			strs := readFile(FILEPATH)
			fmt.Printf("读取数据=%v\n", strs)
			split := strings.Split(strs, ",")
			var nums = make([]int, 1000)
			for i, v := range split {
				atoi, _ := strconv.Atoi(v)
				nums[i] = atoi
			}
			//排序
			sort2.Ints(nums)

			//写入新的文件中
			//for i, v := range nums {
			//	if i == 999 {
			//		writeFile(FILEPATH2, strconv.Itoa(v))
			//	} else {
			//		writeFile(FILEPATH2, strconv.Itoa(v)+",")
			//	}
			//}
			break
		}
	}
	SortExit <- 12
	close(SortExit)
}

//写文件
func writeFile(filePath string, content string) {
	file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println("操作文件失败", err)
	}

	defer func() {
		err2 := file.Close()
		if err2 != nil {
			fmt.Println("关闭文件错误", err2)
		}
	}()

	writer := bufio.NewWriter(file)
	_, err = writer.WriteString(content)
	if err != nil {
		return
	}
	err2 := writer.Flush()
	if err2 != nil {
		fmt.Println("flush失败")
		return
	}
}

//读文件
func readFile(filePath string) string {
	open, err := os.Open(filePath)
	if err != nil {
		log.Fatalln("读取文件错误，路径=", filePath)
	}

	defer open.Close()

	str := ""
	reader := bufio.NewReader(open)
	for true {
		readString, err := reader.ReadString('\n')
		str = str + readString
		if err == io.EOF {
			fmt.Println("读取结束")
			break
		}
	}

	return str
}
